<?php

namespace Trawind\Extension\Commands;

use Illuminate\Console\Command;
use Trawind\Basics\Enums\SystemConstant;
use Trawind\Basics\Exceptions\LogicException;
use Trawind\Extension\Models\Custom\Field;
use Trawind\Extension\Models\Custom\Form;
use Trawind\Extension\Models\Custom\FormField;
use Trawind\Extension\Models\Custom\View;
use Trawind\Extension\Models\Custom\ViewField;
use Illuminate\Support\Facades\DB;
use Trawind\Basics\Traits\Console\SingleTenantConsole;

class SystemFieldCommand extends Command
{

    use SingleTenantConsole;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'system:field {--model=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '收集当前服务所有字段';


    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function exec()
    {
        $model = $this->option('model') ?? $this->getAllModel();
        $modelArr = is_array($model) ? $model : explode(',', $model);
        $prefix = config('database.connections.mysql.prefix');
        $this->info('字段收集中...');
        $bar = $this->output->createProgressBar(count($modelArr));
        $bar->start();

        $viewMaxId = View::system()->max('id');
        $formMaxId = Form::system()->max('id');
        $fieldMaxId = Field::system()->max('id');

        foreach ($modelArr as $modelClass) {
            $modelInstance = app($modelClass);
            $table = $modelInstance->getTable();
            if ($modelInstance->skipMigrateField ?? false) {
                continue;
            }
            $businessTypeId = $modelInstance->businessType or LogicException::error($modelClass.'->businessType Undefined');

            $fields = DB::select('select column_name as name,column_comment as label,ordinal_position as sort from information_schema.columns where table_schema=? and table_name= ?',
                [$this->tenant->tenancy_db_name, $prefix.$table]);

            $view = View::firstOrCreate(
                ['business_type_id' => $businessTypeId],
                [
                    'id' => ++$viewMaxId,
                    'name' => '默认视图',
                    'business_type_id' => $businessTypeId,
                    'is_default' => 1
                ]
            );

            $form = Form::firstOrCreate(
                ['business_type_id' => $businessTypeId],
                [
                    'id' => ++$formMaxId,
                    'name' => '默认表单',
                    'business_type_id' => $businessTypeId,
                    'is_default' => 1
                ]
            );

            $nowFields = [];
            foreach ($fields as $field) {
                $nowFields[] = $field->name;
                $fieldModel = Field::system()->firstOrCreate(
                    ['business_type_id' => $businessTypeId, 'name' => $field->name],
                    [
                        'id' => ++$fieldMaxId,
                        'name' => $field->name,
                        'label' => mb_substr($field->label, 0, 50),
                        'business_type_id' => $businessTypeId,
                        'describe' => $field->label,
                        'widget_type_id' => strpos($field->name, '_at') !== false
                            ? Field::WIDGET_TYPE_ENUM['field_widget_date_time']
                            : Field::WIDGET_TYPE_ENUM['field_widget_input']
                    ]
                );
            }

            $notInFieldIds = Field::system()->where('business_type_id', $businessTypeId)
                ->whereNotIn('name', $nowFields)
                ->get()
                ->pluck('id')
                ->toArray();

            Field::whereIn('id', $notInFieldIds)->delete();
            ViewField::whereIn('field_id', $notInFieldIds)->delete();
            FormField::whereIn('field_id', $notInFieldIds)->delete();
            $bar->advance();
        }
        $bar->finish();
        $this->comment(PHP_EOL."Filling is complete!");
        return 1;
    }


    protected function getAllModel()
    {
        $fqcns = [];

        $allFiles = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(app('path').'/Models'));
        $phpFiles = new \RegexIterator($allFiles, '/\.php$/');
        foreach ($phpFiles as $phpFile) {
            $content = file_get_contents($phpFile->getRealPath());
            $tokens = token_get_all($content);
            $namespace = '';
            for ($index = 0; isset($tokens[$index]); $index++) {
                if (!isset($tokens[$index][0])) {
                    continue;
                }
                if (T_NAMESPACE === $tokens[$index][0]) {
                    $index += 2;
                    while (isset($tokens[$index]) && is_array($tokens[$index])) {
                        $namespace .= $tokens[$index++][1];
                    }
                }
                if (T_CLASS === $tokens[$index][0] && T_WHITESPACE === $tokens[$index + 1][0] && T_STRING === $tokens[$index + 2][0]) {
                    $index += 2;
                    $fqcns[] = $namespace.'\\'.$tokens[$index][1];
                    break;
                }
            }
        }
        return $fqcns;
    }


    protected function getTenantId()
    {
        $tenantId = config('app.env') == 'develop' ? '100000-d' : '100000-p';
        return $this->option('tenant_id') ?? $tenantId;
    }

}
